﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

class ItemFactory
{
    static public ItemFactory Instance = new ItemFactory();
    List<ItemObjectBase> m_ItemObjs = new List<ItemObjectBase>();
    List<string> m_WeaponSmall = new List<string>();
    List<string> m_WeaponMiddle = new List<string>();
    List<string> m_WeaponBig = new List<string>();
    List<string> m_WeaponNetFriend = new List<string>();


    List<string> m_WeaponUAV = new List<string>();
    private ItemFactory()
    {

    }
    public void Init()
    {
        register<AutoGunnery>();
        register<LightMachineGun>();
        register<Tongue_38>();
        register<Railgun_S40>();
        register<ChargeQuickFirer>();
        register<WeatherMonkey>();
        register<ShortSpear>();
        register<LongSpear>();
        register<SunsetGlow>();
        register<Wasp_S1>();
        register<MissileStandard01>();
        register<Viper_S>();
        register<Cupid>();
        register<ThreeLightMachineGun>();
        register<MachineGunnery_27>();
        register<Tripper>();
        register<HoldeLaser>();
        register<Honeycomb_30>();
        register<MissileStandardJ4>();
        register<Gustaf_800>();
        register<HugeSpear>();
        register<Death>();
        register<MissileStandard_10>();
        register<BlueFairy>();

        register<Qiqi_P>();

        register<Saber>();
        register<Jeremy>();


        register<FeOre>();
        register<AgOre>();
        register<AuOre>();

        register<PdOre>();
        register<RedGem>();

        register<OldMetal>();
        register<WinMedal>();
        register<LoseMedal>();
        register<EngineA>();
        register<EngineB>();
        register<EngineC>();
        register<EngineD>();
        initWeaponTypeList();
    }

    void initWeaponTypeList()
    {
        for(int i=0; i< m_ItemObjs.Count; ++i)
        {
            if(m_ItemObjs[i].m_Item.m_Type > Item.ItemsType.WEAPON_BEGIN && 
                m_ItemObjs[i].m_Item.m_Type < Item.ItemsType.WEAPON_END)
            {

                Weapon waepon = m_ItemObjs[i].m_Item as Weapon;
                
                switch (waepon.m_Level)
                {
                    case Weapon.Level.LEVEL_SMALL:
                        m_WeaponSmall.Add(m_ItemObjs[i].m_Name);
                        break;
                    case Weapon.Level.LEVEL_MIDDLE:
                        m_WeaponMiddle.Add(m_ItemObjs[i].m_Name);
                        break;
                    case Weapon.Level.LEVEL_BIG:
                        m_WeaponBig.Add(m_ItemObjs[i].m_Name);
                        break;
                }
            }
            if(m_ItemObjs[i].m_Item.m_Type > Item.ItemsType.NETFRIEND_WEAPON_BEGINE && 
                m_ItemObjs[i].m_Item.m_Type < Item.ItemsType.NETFRIEND_WEAPON_END)
            {
                Weapon waepon = m_ItemObjs[i].m_Item as Weapon;
                m_WeaponNetFriend.Add(m_ItemObjs[i].m_Name);
            }
        }
    }


    public void register<T>() where T : new()
    {
        m_ItemObjs.Add(new ItemObject<T>());
    }

    public Item createItem(string itemName)
    {
        for(int i=0; i< m_ItemObjs.Count; ++i)
        {
            if(m_ItemObjs[i].m_Name == itemName)
            {
                return m_ItemObjs[i].createItem();
            }
        }
        return null;
    }
    public Item createRandomItem()
    {
        int index = 0;
        List<Item> items = new List<Item>();
        for (int i = 0; i < m_ItemObjs.Count; ++i)
        {
            var item = m_ItemObjs[i].createItem();
            index += (int)(item.m_DropRate * 1000);
            item.m_Number = index;
            items.Add(item);
        }
        int randomValue = UnityEngine.Random.Range(0, index);
        for(int i=0; i< items.Count; ++i)
        {
            if(items[i].m_Number > randomValue)
            {
                items[i].m_Number = 1;
                return items[i];
            }
        }
        return null;
    }

    public Item.ItemsType GetItemType(string itemName)
    {
        Item item = createItem(itemName);
        return item.m_Type;
    }

    public bool IsWeapon(Item.ItemsType type)
    {
        bool isWeapon = false;

        if (type > Item.ItemsType.WEAPON_BEGIN &&
            type < Item.ItemsType.WEAPON_END)
        {
            isWeapon = true;
        }
        if (type > Item.ItemsType.NETFRIEND_WEAPON_BEGINE &&
            type < Item.ItemsType.NETFRIEND_WEAPON_END)
        {
            isWeapon = true;
        }
        return isWeapon;
    }
    public bool IsMaterial(Item.ItemsType type)
    {
        bool isTrue = false;

        if (type > Item.ItemsType.MATERIAL_BEGIN &&
            type < Item.ItemsType.MATERIAL_END)
        {
            isTrue = true;
        }
        return isTrue;
    }

    public Weapon createRandomWeaponByLevel(Weapon.Level level, Weapon.Speciality speciality, string influence, bool hasAirplant = false)
    {
        List<string> weaponList = new List<string>();
        List<Weapon> weaponListResult = new List<Weapon>();
        switch (level)
        {
            case Weapon.Level.LEVEL_SMALL:
                weaponList = m_WeaponSmall;
                break;
            case Weapon.Level.LEVEL_MIDDLE:
                weaponList = m_WeaponMiddle;
                break;
            case Weapon.Level.LEVEL_BIG:
                weaponList = m_WeaponBig;
                break;
        }

        foreach (var weaponEnum in weaponList)
        {
            Weapon weapon = null;
            weapon = createItem(weaponEnum) as UAV;
            if (hasAirplant)
            {
                if (weapon == null)
                    continue;
            }
            else
            {
                if (weapon != null)
                    continue;
                weapon = createItem(weaponEnum) as Weapon;
            }
            if (weapon != null && (weapon.ResearchInfluence == InfluenceMG.INFLUENCE_OTHER || weapon.ResearchInfluence == influence) &&
                   speciality == weapon.m_Speciality)
            {
                weaponListResult.Add(weapon);
            }
        }

        if (weaponListResult.Count > 0)
            return weaponListResult[UnityEngine.Random.Range(0, weaponListResult.Count)];
        else
            return null;
    }

    public void Clear()
    {
        m_ItemObjs.Clear();
        m_WeaponSmall.Clear();
        m_WeaponMiddle.Clear();
        m_WeaponBig.Clear();
    }
}

public class ItemObjectBase
{
    public Item m_Item;
    public string m_Name;
    virtual public Item createItem()
    {
        return null;
    }
}

public class ItemObject<T> : ItemObjectBase where T : new()
{
    public ItemObject()
    {
        m_Item = new T() as Item;
        m_Name = m_Item.m_Type.ToString();
    }
    public override Item createItem() 
    {
        return new T() as Item;
    }
}

